package com.hmjk.health.card;

import org.json.JSONObject;
import org.json.JSONException;

import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import com.hmjk.health.HealthApp;
import com.hmjk.health.R;
import com.hmjk.health.background.DataManager;
import com.hmjk.health.background.NetService;
import com.hmjk.health.util.DEV_DATA;
import com.hmjk.health.util.DEV_SET;
import com.hmjk.health.views.SwitchButton;
import com.hmjk.health.views.SwitchButton.OnChangeListener;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.format.Time;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.NumberPicker;
import android.widget.TextView;

public class LocaParamActivity extends Activity implements OnClickListener{
	private final String TAG = LocaParamActivity.class.getSimpleName();
	private HealthApp mApp = null;
	
	private DEV_DATA mDev = null;
	
	private TextView warning = null;
	/*views only for observer*/
	private TextView tvFenceSw = null, tvFenceCt = null, tvFenceRd = null;
	private TextView tvRate = null, tvGps = null;
	GeoCoder mSearch = null;
	private String fenceCtAddr = "";
	
	/*views for admin*/
	private EditText editRadius = null;
	private ImageView radiusErr = null;
	private SwitchButton switchFence = null, switchGPS = null, switchRate = null;
	private NumberPicker ratePicker = null;
	private final int FENCE_MAX_RADIUS = 1000;
	private final int FENCE_MIN_RADIUS = 200;
	private final int REQUEST_FENCE_CT = 1;
	private double localFenceR = 0.0f, localFenceLat = 0.0f, localFenceLng = 0.0f;
	
	/**********************************
	 * 	rate & 0xF000	GPS status
	 *  rate & 0x0F00	rate status
	 *  rate & 0x00FF	rate parameter
	 **********************************/
	private int localRate = 0;
	
	private boolean localFence = false;
	
	private void logd(String info){
		Log.d(TAG,info);
	}
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		mApp = (HealthApp)getApplication();
		
		Intent intent =  getIntent();
		
		mDev = (DEV_DATA)intent.getSerializableExtra("dev");

		if(mDev.admin == 1){
			setContentView(R.layout.dev_param_edit);
			Button butCommit = (Button)findViewById(R.id.commit_but);
			butCommit.setOnClickListener(this);
			editRadius = (EditText)findViewById(R.id.radiusedit);
			radiusErr = (ImageView)findViewById(R.id.rate_err);
			radiusErr.setVisibility(View.INVISIBLE);
			editRadius.setOnFocusChangeListener(new OnFocusChangeListener() {
					
				@Override
				public void onFocusChange(View v, boolean hasFocus) {
					// TODO Auto-generated method stub
					String radius = editRadius.getText().toString().trim();
					int iradius = 0;
					if(radius.isEmpty() == false){
						iradius = Integer.parseInt(radius);
					}
					
					if(hasFocus){
						if(radiusErr.getVisibility() == View.VISIBLE){
							radiusErr.setVisibility(View.INVISIBLE);
							editRadius.setTextColor(0xFF444444);
							if(iradius > FENCE_MAX_RADIUS){
								editRadius.setText(String.valueOf(FENCE_MAX_RADIUS));
							}else if (iradius < FENCE_MIN_RADIUS){
								editRadius.setText(String.valueOf(FENCE_MIN_RADIUS));
							}
						}
					}else {
						
						if((iradius > FENCE_MAX_RADIUS) || (iradius < FENCE_MIN_RADIUS)){
							radiusErr.setVisibility(View.VISIBLE);
							editRadius.setTextColor(0xFFFF0000);
						}
					}
				}
			});
				
			switchFence = (SwitchButton)findViewById(R.id.fencesw);
			switchFence.setOnChangeListener(new OnChangeListener() {
				
				@Override
				public void onChange(SwitchButton sb, boolean state) {
					// TODO Auto-generated method stub
					if(state){
						localFence = true;
					}else {
						localFence = false;
					}
				}
			});
				
			switchGPS = (SwitchButton)findViewById(R.id.gpssw);
			switchGPS.setOnChangeListener(new OnChangeListener() {
					
				@Override
				public void onChange(SwitchButton sb, boolean state) {
					// TODO Auto-generated method stub
					if(state){
						localRate |= 0x1000;
					}else {
						localRate &= 0x0FFF;
					}
				}
			});
			switchRate = (SwitchButton)findViewById(R.id.ratesw);
			switchRate.setOnChangeListener(new OnChangeListener() {
				
				@Override
				public void onChange(SwitchButton sb, boolean state) {
					// TODO Auto-generated method stub
					if(state){
						localRate |= 0x0100;
					}else {
						localRate &= 0xF0FF;
					}
				}
			});
				
			tvRate = (TextView)findViewById(R.id.rateparam);
			tvRate.setOnClickListener(new OnClickListener() {
					
				@Override
				public void onClick(View arg0) {
					// TODO Auto-generated method stub
					int t = localRate&0xFF;
					AlertDialog.Builder builder = new AlertDialog.Builder(LocaParamActivity.this);
					LayoutInflater factory = LayoutInflater.from(LocaParamActivity.this);
					final View entryView = factory.inflate(R.layout.number_picker_dialog, null);
					builder.setView(entryView);
					final String values[] = {"5", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55", "60"};
					ratePicker = (NumberPicker)entryView.findViewById(R.id.numberpicker);
					ratePicker.setDisplayedValues(values);
					ratePicker.setMaxValue(values.length - 1);
					ratePicker.setMinValue(0);
					ratePicker.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS);
					int i = 0;
					for(i=0; i<values.length; i++){
						if(String.valueOf(t).equals(values[i])){
							break;
						}
					}
					i %= values.length;
					ratePicker.setValue(i);
					builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
						
						@Override
						public void onClick(DialogInterface arg0, int arg1) {
							// TODO Auto-generated method stub
							String sRate = values[ratePicker.getValue()];
							tvRate.setText(getResources().getString(R.string.loc_report_rate_unit, sRate));
							int iRate = Integer.parseInt(sRate);
							localRate = (localRate & 0xFF00) + iRate;
						}
					});
					builder.setNegativeButton(R.string.back, new DialogInterface.OnClickListener() {
						
						@Override
						public void onClick(DialogInterface arg0, int arg1) {
							// TODO Auto-generated method stub
							
						}
					});
					builder.create().show();
				}
			});
				
			tvFenceCt = (TextView)findViewById(R.id.fencect);
			tvFenceCt.setOnClickListener(this);
		}else{
			setContentView(R.layout.dev_param_view);
			
			tvFenceSw = (TextView)findViewById(R.id.fence_sw);
			tvFenceCt = (TextView)findViewById(R.id.fence_ct);
			tvFenceRd = (TextView)findViewById(R.id.fence_rd);
			tvRate = (TextView)findViewById(R.id.rate);
			tvGps = (TextView)findViewById(R.id.gps);
		}
		
		mSearch = GeoCoder.newInstance();
		OnGetGeoCoderResultListener listener = new OnGetGeoCoderResultListener() {

			@Override
			public void onGetGeoCodeResult(GeoCodeResult arg0){}

			@Override
			public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
				// TODO Auto-generated method stub
				if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {  
		            //没有找到检索结果  
		        	logd("onGetReverseGeoCodeResult, error");

		        	tvFenceCt.setText("" + localFenceLat + ", " + localFenceLng);
		        	return;
		        }
		        fenceCtAddr = result.getAddress();
		        logd("onGetReverseGeoCodeResult, result:" + fenceCtAddr + "; location:" + result.getLocation());
		        tvFenceCt.setText(fenceCtAddr);
			}
		};
		mSearch.setOnGetGeoCodeResultListener(listener);
		
		TextView title = (TextView) findViewById(R.id.title);
		title.setText(mDev.name);
		
		ImageButton butBack = (ImageButton)findViewById(R.id.back);
		butBack.setOnClickListener(this);
		
		warning = (TextView) findViewById(R.id.warning);
		warning.setVisibility(View.GONE);
		
		refreshData();
	}
	
	@Override
	public void onResume(){
		super.onResume();
		updateView();
	}
	
	@Override
	public void onPause(){
		super.onPause();
		logd("onPause");
		mApp.dismissWaiting();
	}
	
	private void refreshData(){
		mApp.showWaitting(this, null);
		Intent si = new Intent(this, NetService.class);
		si.setAction(NetService.GET_DEV_LOCA_PARAM);
		si.putExtra("uid", mApp.getUID());
		si.putExtra("tid", mDev.id);
		
		Time t = new Time();
		t.setToNow();
		String stamp = "GET_DEV_LOCA_PARAM" + t.toString(); 
		si.putExtra("stamp",stamp);
		mApp.addNetHandler(stamp,mHandler);
		startService(si);
	}
	
	private void updateView(){
		if(mDev == null)
			return;
		
		String[] arg2 = new String[1];
		arg2[0] = mDev.id;
		
		DEV_SET[] data = (DEV_SET[]) mApp.getDataManager().checkData(DataManager.F_DEVICE_SETTINGS, arg2);
		if((data != null) && (data[0] != null)){
			if(data[0].active == false){
				warning.setVisibility(View.VISIBLE);
			}else{
				warning.setVisibility(View.GONE);
			}
		}
		
		if(mDev.admin == 1){
			updateADMINView();
		}else{
			updateOBView();
		}
	}
	
	private void updateADMINView(){
		if(localFence){
			switchFence.setFlage(true);
		}else{
			switchFence.setFlage(false);
		}
		
		String ct = null;
		if((localFenceLat == 0.0f) && (localFenceLng == 0.0f)){
			ct = getResources().getString(R.string.fence_center_unset_text);
		}else{
			ct = getResources().getString(R.string.analyzing);
			LatLng point = new LatLng(localFenceLat, localFenceLng);
			mSearch.reverseGeoCode(new ReverseGeoCodeOption().location(point));
		}
		tvFenceCt.setText(ct);
		
		int para = localRate;
		if((para&0xF000) == 0){
			switchGPS.setFlage(false);
		}else{
			switchGPS.setFlage(true);
		}
		if((para&0x0F00) == 0){
			switchRate.setFlage(false);
		}else{
			switchRate.setFlage(true);
		}
		
		final int itime = (para & 0x0FF);
		String srate = getResources().getString(R.string.loc_report_rate_unit, String.valueOf(itime)); 
		tvRate.setText(srate);
		
		//fence radius
		String rd = String.valueOf((int)(localFenceR));
		editRadius.setText(rd);
		editRadius.setSelection(rd.length());
	}
	
	private void updateOBView(){
		//fence
		String sw = null;
		if(localFence){
			sw = getResources().getString(R.string.fence_switch, getResources().getString(R.string.fence_open));
		}else{
			sw = getResources().getString(R.string.fence_switch, getResources().getString(R.string.fence_closed));
		}
		tvFenceSw.setText(sw);
		String ct = null;
		if((localFenceLat == 0.0f) && (localFenceLng == 0.0f)){
			ct = getResources().getString(R.string.fence_center_unset_text);
		}else{
			ct = getResources().getString(R.string.analyzing);
			LatLng point = new LatLng(localFenceLat, localFenceLng);
			mSearch.reverseGeoCode(new ReverseGeoCodeOption().location(point));
		}
		tvFenceCt.setText(ct);
		
		String rd = getResources().getString(R.string.fence_radius, String.valueOf((int)(localFenceR)));
		tvFenceRd.setText(rd);
		logd("updateStatusView:" + " update fence done");
		
		//location report rate and GPS
		String rate = null;
		String gps = null;
		int para = localRate;
		if((para&0xF000) == 0){
			gps = getResources().getString(R.string.loc_report_gps, getResources().getString(R.string.fence_closed));
		}else{
			gps = getResources().getString(R.string.loc_report_gps, getResources().getString(R.string.fence_open));
		}
		tvGps.setText(gps);
		if((para&0x0F00) == 0){
			rate = getResources().getString(R.string.loc_report_rate_close);
		}else{
			rate = getResources().getString(R.string.loc_report_rate, String.valueOf(para&0xFF));
		}
		tvRate.setText(rate);
		logd("updateStatusView:" + " update location done");
	}
	
	private boolean checkRadiusInput(){
		if(radiusErr.getVisibility() == View.VISIBLE){
			return false;
		}
		
		String radius = editRadius.getText().toString().trim();
		int ir = 0;
		if(radius.isEmpty() == false){
			ir = Integer.parseInt(radius);
		}
		if((ir > FENCE_MAX_RADIUS) || (ir < FENCE_MIN_RADIUS)){
			editRadius.clearFocus();
			return false;
		}else {
			localFenceR = (double)ir;
		}
		return true;
	}
	
	private void commitSetting(){
		Intent si = new Intent(this, NetService.class);
		si.setAction(NetService.SET_DEV_LOCA_PARAM);
		si.putExtra("uid", mApp.getUID());
		si.putExtra("tid", mDev.id);
		si.putExtra("fence", localFence?"1":"0");
		int intFenceR = (int) localFenceR;
		si.putExtra("range", String.valueOf(intFenceR));
		si.putExtra("lat", String.valueOf(localFenceLat));
		si.putExtra("lng", String.valueOf(localFenceLng));
		String rate = Integer.toHexString(localRate).toLowerCase();
		si.putExtra("rate", String.valueOf(rate));
		
		Time t = new Time();
		t.setToNow();
		String stamp = "SET_DEV_LOCA_PARAM" + t.toString(); 
		si.putExtra("stamp",stamp);
		mApp.addNetHandler(stamp,mHandler);
		startService(si);
	}
	
	private Handler mHandler = new Handler(){
		@Override
		public void handleMessage(Message msg){
			switch(msg.what){
			case HealthApp.MSG_NET_RESPONSE:{
				Bundle b = msg.getData();
				String stamp = b.getString("stamp","ooh!No!");
				boolean canceled = b.getBoolean("canceled", false);
				if(stamp.startsWith("GET_DEV_LOCA_PARAM")){
					String sjson = b.getString("json");
					if(sjson != null){
						mApp.dismissWaiting();
						try {
							JSONObject json = new JSONObject(sjson);
							int code = json.getInt("code");
							if(code == 200){
								String state = json.getString("state");
								if(state.equals("00")){
									JSONObject recdata = json.getJSONObject("recdata");
									String f = recdata.getString("fence");
									if(f.equals("1"))
										localFence = true;
									else
										localFence = false;
									
									String range = recdata.getString("range");
									if(range.trim().isEmpty() || range.equalsIgnoreCase("NULL")){
										range = "200";
									}
									localFenceR = Double.parseDouble(range);
									
									String lat = recdata.getString("lat");
									if(lat.trim().isEmpty() || lat.equalsIgnoreCase("NULL")){
										lat = "0.0";
									}
									localFenceLat = Double.parseDouble(lat);
									
									String lng = recdata.getString("lng");
									if(lng.trim().isEmpty() || lng.equalsIgnoreCase("NULL")){
										lng = "0.0";
									}
									localFenceLng = Double.parseDouble(lng);
									
									String rate = recdata.getString("rate");//ffff
									if(rate.trim().isEmpty() || rate.equalsIgnoreCase("NULL")){
										rate = "1105";
									}
									localRate = Integer.parseInt(rate, 16);
									updateView();
									return;
								}
							}
						} catch (JSONException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						mApp.showAlertDialog(LocaParamActivity.this, R.string.network_err);
					}
				}else if(stamp.startsWith("SET_DEV_LOCA_PARAM")){
					String sjson = b.getString("json");
					if(sjson != null){
						mApp.dismissWaiting();
						try {
							JSONObject json = new JSONObject(sjson);
							int code = json.getInt("code");
							if(code == 200){
								String state = json.getString("state");
								if(state.equals("00")){
									mApp.showAlertDialog(LocaParamActivity.this, getResources().getString(R.string.commit_ok), R.string.ok, new OnClickListener() {
											
										@Override
										public void onClick(View arg0) {
											// TODO Auto-generated method stub
											finish();
										}
									});								
									return;
								}
							}
						} catch (JSONException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						mApp.showAlertDialog(LocaParamActivity.this, R.string.commit_err);
					}
				}
			}break;
			}
		}
	};

	@Override
	public void onClick(View v) {
		switch(v.getId()){
		case R.id.back:{
			finish();
		}break;
		
		case R.id.fencect:{
			Intent i = new Intent(this, MapFenceActivity.class);
			i.putExtra("fencelat", localFenceLat);
			i.putExtra("fencelng", localFenceLng);
			startActivityForResult(i, REQUEST_FENCE_CT);
		}break;
		
		case R.id.commit_but:{
			boolean radiusok = true;
			
			radiusok = checkRadiusInput();
			
			if(radiusok == false){
				mApp.showAlertDialog(this, R.string.dev_manager_error);
				return;
			}
			
			mApp.showConfirmDialog(this, getResources().getString(R.string.edit_confirm), new OnClickListener() {
				
				@Override
				public void onClick(View view) {
					// TODO Auto-generated method stub
					if(view.getId() == R.id.alert_but1){
						commitSetting();
					}
				}
			});
			
		}break;
		
		}
	}
	
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data){
		if((requestCode == REQUEST_FENCE_CT) && (resultCode == RESULT_OK)){
			localFenceLat = data.getDoubleExtra("lat", 0.0f);
			localFenceLng = data.getDoubleExtra("lng", 0.0f);
			
		}
	}
}
